﻿package igz.fleaxy.ui.form.input
{
	import flash.events.FocusEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import igz.fleaxy.Fleaxy;
	import igz.fleaxy.util.DateTimeUtil;
	import igz.fleaxy.util.RegExpType;
	import igz.fleaxy.util.RestricType;
	import igz.fleaxy.util.StringUtil;
	import flash.display.Sprite;
	
	import flash.events.KeyboardEvent;
	import igz.fleaxy.ui.text.LabelUi;
	import igz.fleaxy.ui.text.TextUi;
	import igz.fleaxy.util.Convert;
	import igz.fleaxy.util.ObjectUtil;
	
	import flash.text.TextFieldType;
	import flash.text.TextFieldAutoSize;
	
	/**
	 * @author Intelygenz | www.intelygenz.com
	 *
	 * Input de texto clásico y simple
	 *
	 */
	public class Input extends Sprite {
		
		protected var _TextUi:TextUi;
		
		/**
		 * Caja de texto de entrada
		 */
		public function get $TextUi():TextUi {
			return _TextUi;
		}

		protected var _Label:LabelUi;
		/**
		 * Etiqueta de texto
		 */
		public function get $Label():LabelUi {
			return _Label;
		}
		
		protected var _Example:LabelUi;
		
		private var _Name:String;
		
		private var _TimerCheckRestric:Timer;
		
		protected var _Settings:Object = { "width" : 250
										,"label" : ""
										,"margin" : 1
										,"background" : 0xFFFFFF
										,"border" : 0x000000
										,"example" : ""
										,"inputType" : InputType.$TEXT
										,"labelAlign" : "Top"
										,"required" : false
										,"restringed" : false
										,"restringedValues" : { "minValue" : 0
															  , "maxValue" : 50
													          , "forwardRestric" : null
													          , "nextRestric" : null
														      }
										,"inputStyle" : { "labelStyle": ""
														, "exampleStyle": ""
														, "labelStyleRequired": ""
														, "inputTextStyle": ""
														}
										};
		
		public function get $Settings():Object {
			return _Settings;
		}
		
		/**
		 *  Componente para entrada de texto sin saltos de linea
		 *
		 * @param	p_name String
		 * @param	p_settings { "width" : 250
								,"label" : ""
								,"margin" : 1
								,"background" : 0xFFFFFF
								,"border" : 0x000000
								,"example" : ""
								,"inputType" : InputType.$TEXT
								,"labelAlign" : "Top"
								,"required" : false
								,"restringed" : false
								,"restringedValues" : { "minValue" : 0
													  , "maxValue" : 50
													  , "forwardRestric" : null
													  , "nextRestric" : null
													  }
								,"inputStyle" : { "labelStyle": ""
												, "exampleStyle": ""
												, "labelStyleRequired": ""
												, "inputTextStyle": ""
												}
								}
		 *
		 * @example
		 */

		public function Input (p_name:String, p_settings:Object = null) {

			ObjectUtil.$Merge(p_settings, _Settings);

			_Name = p_name;

			_TextUi = new TextUi("",_Settings["inputStyle"]["inputTextStyle"]);
			_TextUi.wordWrap = false;
			_TextUi.multiline = false;
			_TextUi.selectable = true;
			_TextUi.type = TextFieldType.INPUT;
			_TextUi.autoSize = TextFieldAutoSize.NONE;
			_TextUi.htmlText = "";

			if ( _Settings["border"] != null ) {
				_TextUi.border = true;
				_TextUi.borderColor = _Settings["border"];
			}
			
			if ( _Settings["background"] != null ) {
				_TextUi.background = true;
				_TextUi.backgroundColor = _Settings["background"];
			}
			
			_TextUi.width = _Settings["width"];
			_TextUi.height = _TextUi.textHeight + 5;
			addChild(_TextUi);

			if ( _Settings["label"] != "" ) {
				_Label = new LabelUi(_Settings["label"], _Settings["inputStyle"]["labelStyle"]);
				addChild(_Label);
				
				if (_Settings.labelAlign == "Top") {
					_TextUi.y = _Label.y + _Label.height + _Settings["margin"];
				}
				else {
					_TextUi.x = _Label.x + _Label.width + _Settings["margin"];
				}
			}
			
			if ( _Settings["example"] != "" ) {
				_Example =  new LabelUi(_Settings["example"], _Settings["inputStyle"]["exampleStyle"], {"fixWidth":_Settings["width"],"maxLines":1});
				_Example.x = _TextUi.x;
				_Example.y = _TextUi.y;
				addChild( _Example );
			}

			_TextUi.displayAsPassword = (_Settings["inputType"] == InputType.$PASSWORD);

			_TimerCheckRestric = new Timer(500, 1);
			_TimerCheckRestric.addEventListener(TimerEvent.TIMER_COMPLETE, _TimerCheckRestric_OnTimerComplete);

			_SetRestricType();

			$Enable();
		}
		
		
		/**
		 * Si es un textbox de ejemplo lo muestra (o oculta)
		 *
		 * @param	p_forceHide valor que indica si lo debe esconder o no
		 */
		private function _ShowHideExample() : void {
			if ( _Settings["example"] != "" ) {
				if ( _TextUi.text == "" ) {
					_Example.visible = true;
				}
				else {
					_Example.visible = false;
				}
			}
		}

		private function _OnTextUi_FocusIn( p_event: FocusEvent ) : void {
			if ( _Settings["example"] != "" ) {
				_Example.visible = false;
			}
		}
		
		private function _OnTextUi_FocusOut( p_event: FocusEvent ) : void {
			_ShowHideExample();
		}
		
		private function _OnKeyUp( p_event:KeyboardEvent ) : void {
			_StartTimerCheckRestric();
		}
		
		/**
		 * Si tiene un tiempo restringido, lo reinicia
		 */
		private function _StartTimerCheckRestric() : void {
			if ( _Settings["restringed"] ) {
				_TimerCheckRestric.reset();
				_TimerCheckRestric.start();
			}
		}
		

		private function _TimerCheckRestric_OnTimerComplete ( p_event:TimerEvent ) :void {
			_CheckRestric();
		}
		
		/**
		 * Comprueba si el valor introducido está o no en el intervalo restringido
		 */
		private function _CheckRestric () : void {
			var maxValue : Number = _Settings["restringedValues"]["maxValue"] as Number;
			var minValue : Number = _Settings["restringedValues"]["minValue"] as Number;
			
			if ( Convert.$ToNumber(_TextUi.text) < minValue ) {
				_TextUi.text = minValue.toString();
			}
			else if ( Convert.$ToNumber(_TextUi.text) > maxValue )  {
				_TextUi.text = maxValue.toString();
			}
		}
		
		
		/**
		 * Detecta el tipo de restricción que existe.
		 */
		private function _SetRestricType () : void {
			switch ( _Settings["inputType"] ) {
				
				case InputType.$INTEGER:  _TextUi.restrict = RestricType.$INTEGER; 		      break;
				
				case InputType.$DECIMAL:  _TextUi.restrict = RestricType.$DECIMAL; 			  break;
				
				case InputType.$TEXT: 	 _TextUi.restrict = RestricType.$COMMON_CHARS; 		  break;
				
				case InputType.$PASSWORD: _TextUi.restrict = RestricType.$PASSWORD; 		  break;
				
				case InputType.$DATE:	 _TextUi.restrict = RestricType.$DATE;     			  break;
				
				case InputType.$MAIL:	 _TextUi.restrict = RestricType.$MAIL;   			  break;
			}

		}
		
		/**
		 *  Método que comprueba si el valor del campo de texto es válido
		 *
		 * @example $IsValidText( "pedro.sanchez@intelygenz.com", RegExpType.$EMAIL);
		 *
		 */
		public function $Validate () : Boolean {
			var expReg:RegExp;
			var resVal:Boolean;

			switch ( _Settings["inputType"] ) {
			
				case InputType.$TEXT: 	  expReg = RegExpType.$COMMON_CHARS; 		   break;
				case InputType.$INTEGER:  expReg = RegExpType.$INTEGER;                break;
				case InputType.$DECIMAL:  expReg = RegExpType.$DECIMAL;   			   break;
				case InputType.$DATE: 	  expReg = RegExpType.$DATE;  				   break;
				case InputType.$PASSWORD: expReg = RegExpType.$PASSWORD_TYPE_1;	  	   break;
				case InputType.$MAIL: 	  expReg = RegExpType.$MAIL; 				   break;
				case InputType.$URL: 	  expReg = RegExpType.$URL;	 				   break;
			}
			
			return StringUtil.$Validate( _TextUi.text, expReg );
		}
		
		/**
		 * Valor de input
		 */
		public function set $Value ( p_value:* ) : void {
			var value:String = "";
			if ( p_value != null ) {
				switch ( _Settings["inputType"] ) {
					case InputType.$DATE:
						//DateTimeUtil.ParseToDateTimeType();
						break;
					default :
						value = new String(p_value);
						break;
				}
			}
			_TextUi.text = value;
			_TextUi.height = _TextUi.textHeight + 5;
			_ShowHideExample();
		}
		
		public function get $Value () : String {
			return _TextUi.text;
		}
		
		override public function set width ( p_value:Number ) : void {
			_TextUi.width = p_value;
			if ( _Label != null ) {
				_Label.$SetFixWidth( p_value );
			}
		}
		
		
		public function $Enable () : void {

			_TextUi.addEventListener(KeyboardEvent.KEY_UP, _OnKeyUp);
			
			if ( _Settings["example"] != "" ) {
				_TextUi.addEventListener(FocusEvent.FOCUS_IN, _OnTextUi_FocusIn);
				_TextUi.addEventListener(FocusEvent.FOCUS_OUT, _OnTextUi_FocusOut);
			}
			
			_TextUi.type = TextFieldType.INPUT;
			
			this.alpha = 1;
		}
		
		public function $Disable () : void {
			_TextUi.removeEventListener(KeyboardEvent.KEY_UP, _OnKeyUp);
			if ( _Settings["example"] != "" ) {
				_TextUi.removeEventListener(FocusEvent.FOCUS_IN, _OnTextUi_FocusIn);
				_TextUi.removeEventListener(FocusEvent.FOCUS_OUT, _OnTextUi_FocusOut);
			}

// TODO: Investigar porque sucede esto
var text : String = _TextUi.text;
			_TextUi.type = TextFieldType.DYNAMIC;
_TextUi.text = text;

			this.alpha = 0.7;
		}
		
		public function $FocusIn () : void {
			Fleaxy.$Current.$Stage.focus = _TextUi;
		}
		
		public function $FocusOut () : void {
			Fleaxy.$Current.$Stage.focus = Fleaxy.$Current.$Stage;
		}
	}
	
}